﻿using System;
using System.Collections.Generic;
using Development.Tools;
using System.Timers;
using Timer = System.Timers.Timer;


namespace Development.DbData
{
    /// <summary>
    /// 数据库池
    /// </summary>
    public class DbProviderPool
    {
        protected Stack<DbProvider> m_pool = new Stack<DbProvider>();     //对象池
        private Timer m_timer = null;
 
        /// <summary>
        /// 初始化数据库池
        /// </summary>
        /// <param name="dbName"></param>
        /// <param name="num"></param>
        public void InitPool(string connectionName,int num)
        {
            for(int i = 0; i < num; ++i)
            {
                DbProvider p = DbDataHelper.CreateDbProvider(ConfigUtil.GetConnectionSetting(connectionName));
                if(p != null)
                {
                    if(p.Open())
                    {
                        Push(p);
                    }
                }
            }

            m_timer = new Timer(60*60*1000);
            m_timer.Elapsed += new ElapsedEventHandler(KeepPoolLife);
            m_timer.Start();

        }
        /// <summary>
        /// 放入一个对象
        /// </summary>
        /// <param name="item"></param>
        public void Push(DbProvider item)
        {
            if (item == null)
            {
                throw new ArgumentException("AsynObjectPool Items added  cannot be null");
            }
            lock (m_pool)
            {
                m_pool.Push(item);
            }
        }

        /// <summary>
        /// 保持连接活着
        /// </summary>
        private void KeepPoolLife(object obj,ElapsedEventArgs e)
        {
            lock(m_pool)
            {
                foreach(DbProvider p in m_pool)
                {
                    p.KeepLive();
                }
                Log.WriteLog(ELogLevel.LOG_INFO, "db pool count = " + m_pool.Count);
            }
        }

        /// <summary>
        /// 获取一个对象
        /// </summary>
        /// <returns></returns>
        public DbProvider Pop()
        {
            DbProvider item = null;
            lock (m_pool)
            {
                if (m_pool.Count != 0)
                {
                    item = m_pool.Pop();
                }
            }
            return item;
        }

        /// <summary>
        /// 当前池中物品的数量
        /// </summary>
        public int Count
        {
            get
            {
                int count = 0;
                lock (m_pool)
                {
                    count = m_pool.Count;
                }
                return count;
            }

        }

        /// <summary>
        /// 关闭
        /// </summary>
        public void Release()
        {
            lock(m_pool)
            {
                foreach(DbProvider p in m_pool)
                {
                    p.Close();
                }
                m_pool.Clear();
            }
            m_timer.Stop();
        }

        public DbProvider SafeGetProvider()
        {
            DbProvider provider = null;
            while (provider == null)
            {
                provider = Pop();
                ThreadUtils.Sleep(20);
            }
            return provider;
        }

    }
}
